//
//  TestDemo1.swift
//  SwiftUnsafePointer
//
//  Created by edy on 2024/5/31.
//  Copyright © 2024 Riven. All rights reserved.
//

import Foundation


let count = 2
let stride = MemoryLayout<Int>.stride
let aligment = MemoryLayout<Int>.alignment
let byteCount = stride * count

// 原生Raw指针
func testRawPointer() {
    print("raw pointer")
    
    let pointer = UnsafeMutableRawPointer.allocate(byteCount: byteCount, alignment: aligment)
    
    defer {
        pointer.deallocate()
    }
    
    // 存储数据
    pointer.storeBytes(of: 42, as: Int.self)
    // 移动指针
    var tp: UnsafeMutableRawPointer
//    tp = (pointer + stride)
    tp = pointer.advanced(by: stride)
    
    tp.storeBytes(of: 6, as: Int.self)
    
    // 读取数据
    var tValue = pointer.load(as: Int.self)
    print(tValue)
    
    tValue = pointer.advanced(by: stride).load(as: Int.self)
    print(tValue)
    
    // UnsafeRawBufferPointer 类型以字节流的形式来读取内存
    let bufPointer = UnsafeRawBufferPointer(start: pointer, count: byteCount)
    for (i, byte) in bufPointer.enumerated() {
        print("buf \(i): \(byte)")
    }
//    bufPointer.withMemoryRebound(to: Int.self) { buffer in
//
//    }
}

// 类型指针
func testTypePointer() {
    print("type pointer")
    
    let pointer = UnsafeMutablePointer<Int>.allocate(capacity: count)
    pointer.initialize(repeating: 0, count: count)
    
    defer {
        pointer.deinitialize(count: count)
        pointer.deallocate()
    }
    
    // 存储/读取
    pointer.pointee = 42
//    (pointer + 1).pointee = 6
    pointer.advanced(by: 1).pointee = 6
    
    var tValue = pointer.pointee
    print(tValue)
    
    tValue = pointer.advanced(by: 1).pointee
    print(tValue)
    
    let bufPointer = UnsafeBufferPointer(start: pointer, count: count)
    for (i, value) in bufPointer.enumerated() {
        print("value \(i): \(value)")
    }
}

func testRawPointerToTypePointer() {
    print("Coverting raw pointer to type pointer")
    
    // 原生指针
    let rawPointer = UnsafeMutableRawPointer.allocate(byteCount: byteCount, alignment: aligment)
    
    defer {
        rawPointer.deallocate()
    }
    
    // 将原生指针绑定类型
    let typePointer = rawPointer.bindMemory(to: Int.self, capacity: count)
    typePointer.initialize(repeating: 0, count: count)
    defer {
        typePointer.deinitialize(count: count)
    }
    
    typePointer.pointee = 42
    typePointer.advanced(by: 1).pointee = 9
    var tValue = typePointer.pointee
    print(tValue)
    tValue = (typePointer + 1).pointee
    print(tValue)
    
//    let bufPointer = UnsafeBufferPointer(start: typePointer, count: count)
//    for (i, value) in bufPointer.enumerated() {
//        print("value \(i): \(value)")
//    }
    let bufPointer = typePointer.withMemoryRebound(to: UInt8.self, capacity: byteCount) { pointer in
        for i in 0..<byteCount {
            print((pointer+i).pointee)
        }
        return pointer
    }
//    for (i, value) in bufPointer.enumerated() {
//        print("value \(i): \(value)")
//    }
    for i in 0..<byteCount {
        print((bufPointer+i).pointee)
    }
    
    let intPtr = rawPointer.assumingMemoryBound(to: Int.self)
    let bufPointer2 = UnsafeMutableBufferPointer(start: intPtr, count: count)
    for (i, value) in bufPointer2.enumerated() {
        print("value \(i): \(value)")
    }
}

struct Sample {
    
    var number: Int
    var flag: Bool
    var numList: [[Int]]
    
}

// demo
func testDemo() {
    print("test demo")
    
    var sample = Sample(number: 44, flag: true, numList: [[1, 2], [2, 3]])
    
//    let tp = withUnsafePointer(to: &sample) { tp in
//        return tp
//    }
//
//    print(tp)
//    guard let pList = tp.pointer(to: \.numList) else {
//        return
//    }
//    print(pList)
//    print(pList.pointee)
//    pList.withMemoryRebound(to: Int.self, capacity: 4) { pointer in
//
//    }
    
    let pSample = withUnsafeMutablePointer(to: &sample) { tp in
        print("tp = \(tp)")
        return tp
    }
    
    print("pSample = \(pSample)")
    
    guard let plist = pSample.pointer(to: \.numList) else {
        return
    }
    
    print("plist = \(plist)")
    for (i, iItem) in plist.pointee.enumerated() {
        for (j, jItem) in iItem.enumerated() {
            print("i = \(i), j = \(j), item = \(jItem)")
        }
    }
}

func testCSampleDemo() {
    print("Test CSample Demo")

    var cSample = CSample(a: 12, list: ((0, 0, 0, 0), (1, 1, 1, 1), (2, 2, 2, 2), (3, 3, 3, 3), (4, 4, 4, 4), (5, 5, 5, 5), (6, 6, 6, 6), (7, 7, 7, 7)))
    print(cSample)
    
//    cSample.list.0.0 = 1
    let bandNum = Int(c_bandNum_sf)
    let kneeNum = Int(c_kneeNum)
    let count = bandNum * kneeNum
    
    let pSample = withUnsafeMutablePointer(to: &cSample) { tp in
        return tp
    }
    print(pSample)
    
    guard let plist = pSample.pointer(to: \.list) else {
        return
    }
    
//    let pTuple = plist.withMemoryRebound(to: (Int32, Int32, Int32, Int32).self, capacity: kneeNum) { pointer in
//        return pointer
//    }
//    for i in 0..<kneeNum {
//        let ip = (pTuple + i)
//        let tp = ip.withMemoryRebound(to: Int32.self, capacity: kneeNum) { pointer in
//            return UnsafeBufferPointer(start: pointer, count: kneeNum)
//        }
//
//        for iValue in tp {
//            print("iValue = \(iValue)")
//        }
//    }
    
    let pInt32List = plist.withMemoryRebound(to: Int32.self, capacity: count) { pointer in
        return pointer
    }
    
    let pBuf = UnsafeBufferPointer(start: pInt32List, count: count)
    for i in 0..<bandNum {
        let row = i * kneeNum
        for j in 0..<kneeNum {
            let column = j
            let index = row + column
            print("pBuf, i = \(i), j = \(j), index = \(index), iValue = \(pBuf[index])")
        }
    }
}
